using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using ExtendedMvc.Common.Diagnostics;
using ExtendedMvc.Elements;

namespace ExtendedMvc {
	public static class HtmlListExtensions {
		public static ListItem ListItem<T>(this ModelViewHtmlHelper<T> html, object content = null, string id = null) where T : class {
			return new ListItem(id).Content(content);
		}

		public static ListItem ListItem<T>(this ModelViewHtmlHelper<T> html, Expression<Func<T, object>> expression, string id = null) where T : class {
			return new ListItem(id).Content(expression.GetValueFrom(html.ViewDataContainer.Model));
		}

		public static UnorderedList UnorderedList<T>(this ModelViewHtmlHelper<T> html, IEnumerable<string> items = null, string id = null) where T : class {
			if (items == null) return new UnorderedList(id);
			return new UnorderedList(id).Items(items);
		}

		public static UnorderedList UnorderedList<T>(this ModelViewHtmlHelper<T> html, Expression<Func<T, object>> expression, string id = null) where T : class {
			var content = expression.GetValueFrom(html.ViewDataContainer.Model);
			if (content == null) return new UnorderedList(id);
			if (content is IEnumerable<ListItem>) return new UnorderedList(id).Items(content as IEnumerable<ListItem>);
			if (content is IEnumerable<string>) return new UnorderedList(id).Items(content as IEnumerable<string>);
			if (content is IEnumerable) return new UnorderedList(id).Items((content as IEnumerable).Cast<string>());
			if (content is ListItem) return new UnorderedList(id).AddItem((content as ListItem));
			if (content is string) return new UnorderedList(id).AddItem((content as string));
			Check.Argument.IsNotValid(null, "expression", (_) => { return false; }, "The expression return type is invalid.");
			return null;
		}

		public static OrderedList OrderedList<T>(this ModelViewHtmlHelper<T> html, IEnumerable<string> items = null, string id = null) where T : class {
			if (items == null) return new OrderedList(id);
			return new OrderedList(id).Items(items);
		}

		public static OrderedList OrderedList<T>(this ModelViewHtmlHelper<T> html, Expression<Func<T, object>> expression, string id = null) where T : class {
			var content = expression.GetValueFrom(html.ViewDataContainer.Model);
			if (content == null) return new OrderedList(id);
			if (content is IEnumerable<ListItem>) return new OrderedList(id).Items(content as IEnumerable<ListItem>);
			if (content is IEnumerable<string>) return new OrderedList(id).Items(content as IEnumerable<string>);
			if (content is IEnumerable) return new OrderedList(id).Items((content as IEnumerable).Cast<string>());
			if (content is ListItem) return new OrderedList(id).AddItem((content as ListItem));
			if (content is string) return new OrderedList(id).AddItem((content as string));
			Check.Argument.IsNotValid(null, "expression", (_) => { return false; }, "The expression return type is invalid.");
			return null;
		}
	}
}
